[UE]PushModel属性同步
PushModel属性同步
优势
PushModel 是对 Replicate 的一个优化。
对于属性的同步,原有的 Replicated 属性,在 Replicate 之前需要通过反射对一个 Actor 的所有属性进行 diff,对比所有的属性是否发生变化,变化的属性才进行同步。
而用上了 PushModel,我们可以主动 MARK_DIRTY,在 Set 时主动将其设置为脏,相当于给该属性上了一个Flag,底层会自动通过这个Flag 来判断是否需要同步,省去了 diff 这个高消耗的操作。
需要注意的是,对于一个 Actor,如果采用了 PushModel,则需要将所有需要同步的属性都挂上这个 PushModel,否则如果存在非PushModel的需要Repilicated 的属性,可能会该功能不生效,退化到原来的情况。
UE5 中还对 PushModel 做了更进一步的优化,添加了一些新的宏以及对更多基础组件的支持。
实践
设置依赖
首先,我们需要在 Build.cs 中添加 NetCore 模块的依赖。
1 | PublicDependcyModuleNames.AddRange(new string[] {"NetCore"}) |
设置属性
我们对于一个需要同步的属性,得先加上 Replicated 标签;有必要的话,需要加上RepilicatedUsing 来设置属性为脏时执行的回调函数。
1 | UCLASS() |
1 | void ATest::OnRep_Param() {...} |
声明同步
首先我们要先将这个 Actor 标记为需要同步,在构造函数中标记 bReplicates = true。
接着我们需要实现 GetLifetimeReplicatedProps,在这个接口中添加宏标记同步的 Property。
1 | void ATest::GetLifetimeReplicatedProps(TArray< FLifetimeProperty >& OutLifetimeProps) const |
FDoRepLifetimeParams 中设置了同步的条件,其中bIsPushBased 表明是否使用 PushModel。
其中 DOREPLIFETIME_WITH_PARAMS_FAST 的宏实现:
1 | define DOREPLIFETIME_WITH_PARAMS_FAST(c,v,params) \ |
修改属性
最后,我们在修改属性的时候,可以使用 MARK_PROPERTY_DIRTY_FROM_NAME 来将属性设脏。
1 | void ATest::SetParam(const float NewParam) |
现在,Server 只需要检测属性是否被 MARK_DIRTY 就可以知道是否需要同步。
当然,除了 MARK_PROPERTY_DIRTY_FROM_NAME 以外,UE 还实现了一些作用类似的其它的宏:
1 |
改进
当然,我们也可以不这么复杂,我们可以自己设置一个新的标签。
对于打上这个标签的属性,让其在 CodeGenerator 中自动生成 Setter 与 Getter,然后通过 Setter 与 Getter 来进行修改与访问。
1 | template<typename _T> \ |
参考
Unreal Engine 4. New network model: PushModel:https://tech-en.netlify.app/articles/en539604/index.html



